.386
.model flat, stdcall
option casemap :none

	include	\masm32\include\windows.inc
	include \masm32\include\kernel32.inc
	include \masm32\include\user32.inc

	includelib \masm32\lib\kernel32.lib
	includelib \masm32\lib\user32.lib

	DialogProc proto :DWORD, :DWORD, :DWORD, :DWORD

.data
caption		db "Сложное использование шаблона", 0
wcaption	db sizeof caption * 2 dup(0)
stattext	db "Элемент управления STATIC", 0
wstattext	db sizeof stattext * 2 dup(0)
btntext		db "Кнопка", 0
wbtntext	db sizeof btntext * 2 dup (0)
fontname	db "MS Sans Serif", 0
wfont		db sizeof fontname * 2 dup(0)
dlgTemplate	dd 0

.data?
hInstance	HINSTANCE ?
CommandLine	LPSTR ?
dlgtmp		DLGTEMPLATE <>
dlgitmp		DLGITEMTEMPLATE <>

.code
start:

invoke	GetModuleHandle, NULL
mov	hInstance, eax
invoke	GetCommandLine
mov	CommandLine, eax


; подготавливаем байтовый массив, включающий структуру DLGTEMPLATE, заголовок и дополнительные байты

; конвертируем текст заголовка окна ASCII->UNICODE
invoke  MultiByteToWideChar, CP_ACP, 0, addr caption, -1, addr wcaption, sizeof wcaption - 2
mov eax, sizeof wcaption - 2

; конвертируем имя шрифта ASCII->UNICODE
invoke  MultiByteToWideChar, CP_ACP, 0, addr fontname, -1, addr wfont, sizeof wfont - 2
add eax, sizeof wfont - 2

; конвертируем текст статика ASCII->UNICODE
invoke  MultiByteToWideChar, CP_ACP, 0, addr stattext, -1, addr wstattext, sizeof wstattext - 2
add eax, sizeof wstattext - 2

; конвертируем текст кнопки ASCII->UNICODE
invoke  MultiByteToWideChar, CP_ACP, 0, addr btntext, -1, addr wbtntext, sizeof wbtntext - 2
add eax, sizeof wbtntext - 2

add eax, sizeof DLGTEMPLATE
add eax, sizeof DLGITEMTEMPLATE

; резервируем память под байтовый массив шаблона диалога
invoke VirtualAlloc, NULL, eax, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE
mov dlgTemplate, eax

; заполняем структуру DLGTEMPLATE (12 bytes)
mov dlgtmp.style, WS_VISIBLE or WS_CAPTION or WS_SYSMENU or DS_CENTER or DS_SETFONT
mov dlgtmp.dwExtendedStyle, 0
mov dlgtmp.cdit, 2
mov dlgtmp.x, 0
mov dlgtmp.y, 0
mov dlgtmp.lx, 221
mov dlgtmp.ly, 121

; закидываем данные в массив
mov edi, dlgTemplate
; структуру DLGTEMPLATE
mov esi, offset dlgtmp
mov ecx, sizeof DLGTEMPLATE
rep movsb
; меню и класс 4 байта
add edi, 4
; заголовок
mov esi, offset wcaption
mov ecx, sizeof wcaption
rep movsb
; размер шрифта
mov word ptr[edi], 0008h
add edi, 2
; название шрифта
mov esi, offset wfont
mov ecx, sizeof wfont
rep movsb

; заполняем структуру DLGITEMTEMPLATE для статика (12 bytes)
mov dlgitmp.style, WS_CHILD or WS_VISIBLE or WS_TABSTOP
mov dlgitmp.dwExtendedStyle, 0
mov dlgitmp.x, 50
mov dlgitmp.y, 40
mov dlgitmp.lx, 130
mov dlgitmp.ly, 22
mov dlgitmp.id, 1002

; структуру DLGITEMTEMPLATE в массив
mov esi, offset dlgitmp
mov ecx, sizeof DLGITEMTEMPLATE
rep movsb
; флаг наличия контрола и его класс
mov dword ptr[edi], 0082FFFFh
add edi, 4
; текст контрола
mov esi, offset wstattext
mov ecx, sizeof wstattext
rep movsb

add edi, 2

; заполняем структуру DLGITEMTEMPLATE для кнопки (12 bytes)
mov dlgitmp.style, WS_CHILD or WS_VISIBLE or WS_TABSTOP
mov dlgitmp.dwExtendedStyle, 0
mov dlgitmp.x, 73
mov dlgitmp.y, 80
mov dlgitmp.lx, 74
mov dlgitmp.ly, 22
mov dlgitmp.id, 1003

; структуру DLGITEMTEMPLATE в массив
mov esi, offset dlgitmp
mov ecx, sizeof DLGITEMTEMPLATE
rep movsb
; флаг наличия контрола и его класс
mov dword ptr[edi], 0080FFFFh
add edi, 4
; текст контрола
mov esi, offset wbtntext
mov ecx, sizeof wbtntext
rep movsb

add edi, 2

; создаем окно диалога
invoke	DialogBoxIndirectParam, hInstance, dlgTemplate, NULL, addr DialogProc, 0

; освободжаем память, использованную под байтовый массив шаблона диалога 
invoke	VirtualFree, dlgTemplate, 0, MEM_RELEASE

; стандартный выход
invoke	ExitProcess, eax

DialogProc proc hDlg:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
	.if uMsg == WM_INITDIALOG
	.elseif uMsg == WM_COMMAND
		.if wParam == 1003
			invoke SendMessage, hDlg, WM_CLOSE, 0, 0
		.endif
	.elseif uMsg == WM_CLOSE
		invoke EndDialog, hDlg, 0
		ret
	.endif
	xor	eax, eax
	ret
DialogProc endp

end start
